# coding=utf-8
__author__ = 'liubin'

from decimal import Decimal
from datetime import datetime
from tornado.web import authenticated, asynchronous
from sqlalchemy import or_, desc, and_, exists
from sqlalchemy.orm import contains_eager
from tornado_json.requesthandlers import APIHandler
from project.tools import HandlerMixin, unblock, to_json
from project.tools.constants import DyeingOrderType
from project.models import DyeingOrder, DyeingOrderDetail, Customer


class DyeingOrderHandler(HandlerMixin, APIHandler):
    """
    供应商API
    """
    __url_names__ = []

    @asynchronous
    def check_no_not_exist(self, no):
        """
        检查编码存在
        """
        record = self.db_conn.query(DyeingOrder).filter(
            and_(
                DyeingOrder.no == no
            )
        ).first()
        if record:
            self.error(u'指定订单编号已被使用')
            return False
        return True

    @asynchronous
    def check_id_exist(self, id):
        """
        检查ID存在
        """
        record = self.db_conn.query(DyeingOrder).join(DyeingOrder.detail).filter(
            and_(
                DyeingOrder.id == id,
                DyeingOrder.status != DyeingOrderType.deleted.value,
                DyeingOrderDetail.status != DyeingOrderType.deleted.value,
            )
        ).first()
        if not record:
            self.error(u'指定订单不存在')
        return record


class SingleHandler(DyeingOrderHandler):
    """
    单条记录处理
    """
    __urls__ = [r"/api/dyeingOrder/(?P<id>[a-zA-Z0-9_]+)/?"]

    @authenticated
    @unblock
    def get(self, id):
        """
        获得单条记录
        :param id:
        :return:
        """
        record = self.check_id_exist(id)
        if record:
            # 结合查询，多表结合要分段写
            record = self.db_conn.query(DyeingOrder).join(DyeingOrder.customer).join(DyeingOrder.detail, DyeingOrderDetail.category).join(
                DyeingOrder.detail, DyeingOrderDetail.color).options(
                contains_eager(DyeingOrder.customer)).options(
                contains_eager(DyeingOrder.detail, DyeingOrderDetail.category)).options(
                contains_eager(DyeingOrder.detail, DyeingOrderDetail.color)).filter(
                and_(
                    DyeingOrder.id == id,
                    DyeingOrder.status != DyeingOrderType.deleted.value,
                    DyeingOrderDetail.status != DyeingOrderType.deleted.value,
                )
            ).scalar()
                #.first()
            print('detail:', record)
            self.success(to_json(record))

    @authenticated
    @unblock
    def put(self, id):
        """
        更新单条记录
        :param id:
        :return:
        """
        record = self.check_id_exist(id)
        if record:
            json = self.json_args
            orderDate = json.get('orderDate');
            if orderDate:
                record.orderDate = datetime.strptime(orderDate, '%Y%m%d')
            # supplier.name = data.get('name')
            # supplier.address = data.get('address')
            self.db_conn.commit()
            self.success(None)

    @authenticated
    @unblock
    def delete(self, id):
        """
        删除
        """
        record = self.check_id_exist(id)
        if record:
            record.status = DyeingOrderType.deleted.value
            self.db_conn.commit()
            self.success(None)
class SingleHandler(DyeingOrderHandler):
    """
    单条记录处理
    """
    __urls__ = [r"/api/dyeingOrder/(?P<id>[a-zA-Z0-9_]+)/?"]

    @authenticated
    @unblock
    def get(self, id):
        """
        获得单条记录
        :param id:
        :return:
        """
        record = self.check_id_exist(id)
        if record:
            # 结合查询，多表结合要分段写
            record = self.db_conn.query(DyeingOrder).join(DyeingOrder.customer).join(DyeingOrder.detail, DyeingOrderDetail.category).join(
                DyeingOrder.detail, DyeingOrderDetail.color).options(
                contains_eager(DyeingOrder.customer)).options(
                contains_eager(DyeingOrder.detail, DyeingOrderDetail.category)).options(
                contains_eager(DyeingOrder.detail, DyeingOrderDetail.color)).filter(
                and_(
                    DyeingOrder.id == id,
                    DyeingOrder.status != DyeingOrderType.deleted.value,
                    DyeingOrderDetail.status != DyeingOrderType.deleted.value,
                )
            ).scalar()
                #.first()
            print('detail:', record)
            self.success(to_json(record))

    @authenticated
    @unblock
    def put(self, id):
        """
        更新单条记录
        :param id:
        :return:
        """
        record = self.check_id_exist(id)
        if record:
            json = self.json_args
            orderDate = json.get('orderDate');
            if orderDate:
                record.orderDate = datetime.strptime(orderDate, '%Y%m%d')
            # supplier.name = data.get('name')
            # supplier.address = data.get('address')
            self.db_conn.commit()
            self.success(None)

    @authenticated
    @unblock
    def delete(self, id):
        """
        删除
        """
        record = self.check_id_exist(id)
        if record:
            record.status = DyeingOrderType.deleted.value
            self.db_conn.commit()
            self.success(None)

class DownloadHandler(DyeingOrderHandler):
    """
    单条记录处理
    """
    __urls__ = [r"/api/dyeingOrder/(?P<id>[a-zA-Z0-9_]+)/download/?"]

    @authenticated
    @unblock
    def get(self, id):
        with open('report/order.pdf', 'rb') as f:
            self.set_header("Content-Type", 'application/pdf; charset="utf-8"')
            self.set_header("Content-Disposition", "attachment; filename=test.pdf")
            self.write(f.read())
        """
        获得单条记录
        :param id:
        :return:
        """
        # record = self.check_id_exist(id)
        # if record:
        #     # 结合查询，多表结合要分段写
        #     record = self.db_conn.query(DyeingOrder).join(DyeingOrder.customer).join(DyeingOrder.detail, DyeingOrderDetail.category).join(
        #         DyeingOrder.detail, DyeingOrderDetail.color).options(
        #         contains_eager(DyeingOrder.customer)).options(
        #         contains_eager(DyeingOrder.detail, DyeingOrderDetail.category)).options(
        #         contains_eager(DyeingOrder.detail, DyeingOrderDetail.color)).filter(
        #         and_(
        #             DyeingOrder.id == id,
        #             DyeingOrder.status != DyeingOrderType.deleted.value,
        #             DyeingOrderDetail.status != DyeingOrderType.deleted.value,
        #         )
        #     ).scalar()
        #         #.first()
        #     print('detail:', record)
        #     self.success(to_json(record))


class ListHandler(DyeingOrderHandler):
    """
    记录列表
    """
    __urls__ = [r'/api/dyeingOrder/?']

    @authenticated
    @unblock
    def get(self):
        """
        获取记录列表
        :return:
        """
        # 无关字段, 原样返回
        draw = self.get_query_argument('draw', 0)
        # 分页大小
        size = int(self.get_query_argument('size', 0))
        # 第几项开始
        start = int(self.get_query_argument('start', 0))
        # 查询字段
        query = self.get_query_argument('query', '')
        # 排序字段
        order = self.get_query_argument('order', '')
        # 正序或倒叙
        sort = self.get_query_argument('dir', '')
        end = start + size
        sb = self.db_conn.query(DyeingOrderDetail).filter(DyeingOrderDetail.status != DyeingOrderType.deleted.value)\
        .subquery('t')
        records = self.db_conn.query(DyeingOrder).join(DyeingOrder.customer).options(
            contains_eager(DyeingOrder.customer)).filter(
            and_(
                DyeingOrder.status != DyeingOrderType.deleted.value,
            ),
            exists().where(sb.c.order_id == DyeingOrder.id)
        )
        if query:
            pass
            # records = records.filter(
            #     or_(
            #         DyeingOrder.status!=DyeingOrderType.deleted.value
            #         # Supplier.code.like('%' + query + '%'),
            #         # Supplier.name.like('%' + query + '%'),
            #         # Supplier.address.like('%' + query + '%')
            #     )
            # )
        if order:
            if sort == 'desc':
                records = records.order_by(desc(getattr(DyeingOrder, order)))
            else:
                records = records.order_by(getattr(DyeingOrder, order))
        # 总件数
        total = records.count()
        if end:
            # 分页处理
            records = records.slice(start, end)
        # 获取list对象
        records = records.all()
        # 返回值
        print(to_json(records))

        self.success(to_json(records), draw=draw, total=total)

    @authenticated
    @unblock
    def post(self):
        """
        新增
        :return:
        """
        json = self.json_args;
        orderDate = json.get('orderDate');
        # 日期处理
        if orderDate:
            json['orderDate'] = datetime.strptime(orderDate, '%Y%m%d')
        record = DyeingOrder(json)
        if self.check_no_not_exist(record.no):
            details = json.get('detail');
            self.db_conn.add(record)
            # 必须先刷新
            self.db_conn.flush()
            amount = 0
            for detail in details:
                record_detail = DyeingOrderDetail(detail)
                record_detail.orderId = record.id
                # 计算前转化为decimal
                record_detail.amount = Decimal(record_detail.price) * Decimal(record_detail.count)
                amount += record_detail.amount
                self.db_conn.add(record_detail)
            record.amount = amount
            self.db_conn.commit()
            self.success(None)
